/**
 @file ctc_lb_hash.h

 @author  Copyright (C) 2021 Centec Networks Inc.  All rights reserved.

 @date 2021-7-26

 @version v1.0

   This file contains all lb hash related data structure, enum, macro and proto.
*/

#ifndef _CTC_LB_HASH_H
#define _CTC_LB_HASH_H

#ifdef __cplusplus
extern "C" {
#endif

#define CTC_LB_HASH_GRP_NUM 8
#define CTC_LB_HASH_ECMP_GLOBAL_PROFILE 0xFF
#define CTC_LB_HASH_GLOBAL_PROFILE 0xFF

enum ctc_lb_hash_field_e
{
    CTC_LB_HASH_FIELD_MACDA_LO = 0x00000001,            /**< [TM.TMM.AT] MAC DA low 16 bits */
    CTC_LB_HASH_FIELD_MACDA_MI = 0x00000002,            /**< [TM.TMM.AT] MAC DA middle 16 bits */
    CTC_LB_HASH_FIELD_MACDA_HI = 0x00000004,            /**< [TM.TMM.AT] MAC DA high 16 bits */

    CTC_LB_HASH_FIELD_MACSA_LO = 0x00000008,            /**< [TM.TMM.AT] MAC SA low 16 bits */
    CTC_LB_HASH_FIELD_MACSA_MI = 0x00000010,            /**< [TM.TMM.AT] MAC SA middle 16 bits */
    CTC_LB_HASH_FIELD_MACSA_HI = 0x00000020,            /**< [TM.TMM.AT] MAC SA high  16 bits */

    CTC_LB_HASH_FIELD_SVLAN     = 0x00000040,           /**< [TM.TMM.AT] SVLAN ID */
    CTC_LB_HASH_FIELD_CVLAN     = 0x00000080,           /**< [TM.TMM.AT] CVLAN ID */

    CTC_LB_HASH_FIELD_ETHER_TYPE = 0x00000100,          /**< [TM.TMM.AT] Ether type */

    CTC_LB_HASH_FIELD_IP_DA_LO = 0x00000200,            /**< [TM.TMM.AT] IP DA low 16 bits */
    CTC_LB_HASH_FIELD_IP_DA_HI = 0x00000400,            /**< [TM.TMM.AT] IP DA high 16 bits */
    CTC_LB_HASH_FIELD_IP_SA_LO = 0x00000800,            /**< [TM.TMM.AT] IP SA low 16 bits */
    CTC_LB_HASH_FIELD_IP_SA_HI = 0x00001000,            /**< [TM.TMM.AT] IP sA high 16 bits */

    CTC_LB_HASH_FIELD_SRC_CHIP_ID = 0x00002000,         /**< [TM.TMM.AT] Source chip id */
    CTC_LB_HASH_FIELD_DST_CHIP_ID = 0x00004000,         /**< [TM.TMM.AT] Destination chip_id */
    CTC_LB_HASH_FIELD_SRC_PORT = 0x00008000,            /**< [TM.TMM.AT] Source port */
    CTC_LB_HASH_FIELD_DST_PORT = 0x00010000,            /**< [TM.TMM.AT] Destination port */

    CTC_LB_HASH_FIELD_FLOWLABEL_LO = 0x00020000,        /**< [TM.TMM.AT] IPv6 flow label low 16 bits */
    CTC_LB_HASH_FIELD_FLOWLABEL_HI = 0x00040000,        /**< [TM.TMM.AT] IPv6 flow label high 4 bits */

    CTC_LB_HASH_FIELD_PROTOCOL     = 0x00080000,        /**< [TM.TMM.AT] Layer3 protocol */

    CTC_LB_HASH_FIELD_UDF_LO = 0x00100000,              /**< [TM.TMM.AT] Udf low 16 bits */
    CTC_LB_HASH_FIELD_UDF_HI = 0x00200000,              /**< [TM.TMM.AT] Udf high 16 bits */

    CTC_LB_HASH_FIELD_VNI_LO = 0x00400000,              /**< [TM.TMM.AT] Vni(vxlan/nvgre) low 16 bits */
    CTC_LB_HASH_FIELD_VNI_HI = 0x00800000,              /**< [TM.TMM.AT] Vni(vxlan/nvgre) high 8 bits */

    CTC_LB_HASH_FIELD_L4_DSTPORT = 0x01000000,          /**< [TM.TMM.AT] Destination layer4 port */
    CTC_LB_HASH_FIELD_L4_SRCPORT = 0x02000000,          /**< [TM.TMM.AT] Source layer4 port */

    CTC_LB_HASH_FIELD_GRE_KEY_LO   = 0x01000000,        /**< [TM.TMM.AT] GRE key low 16 bits */
    CTC_LB_HASH_FIELD_GRE_KEY_HI   = 0x02000000,        /**< [TM.TMM.AT] GRE key high 16 bits */
    CTC_LB_HASH_FIELD_GRE_PROTOCOL = 0x04000000,        /**< [TM.TMM.AT] GRE protocol */

    CTC_LB_HASH_FIELD_LABEL0_LO = 0x01000000,           /**< [TM.TMM.AT] MPLS label0 low 16 bits */
    CTC_LB_HASH_FIELD_LABEL0_HI = 0x02000000,           /**< [TM.TMM.AT] MPLS label0 high 16 bits */
    CTC_LB_HASH_FIELD_LABEL1_LO = 0x04000000,           /**< [TM.TMM.AT] MPLS label1 low 16 bits */
    CTC_LB_HASH_FIELD_LABEL1_HI = 0x08000000,           /**< [TM.TMM.AT] MPLS label1 high 16 bits */
    CTC_LB_HASH_FIELD_LABEL2_LO = 0x10000000,           /**< [TM.TMM.AT] MPLS label2 low 16 bits */
    CTC_LB_HASH_FIELD_LABEL2_HI = 0x20000000,           /**< [TM.TMM.AT] MPLS label2 high 16 bits */

    CTC_LB_HASH_FIELD_FCOE_SID_LO  = 0x01000000,        /**< [TM.TMM.AT] FCOE source fcid low 16 bits */
    CTC_LB_HASH_FIELD_FCOE_SID_HI  = 0x02000000,        /**< [TM.TMM.AT] FCOE source fcid high 16 bits */
    CTC_LB_HASH_FIELD_FCOE_DID_LO  = 0x04000000,        /**< [TM.TMM.AT] FCOE dest fcid low 16 bits */
    CTC_LB_HASH_FIELD_FCOE_DID_HI  = 0x08000000,        /**< [TM.TMM.AT] FCOE dest fcid high 16 bits */

    CTC_LB_HASH_FIELD_INGRESS_NICKNAME  = 0x01000000,   /**< [TM.TMM.AT] ingress nickname */
    CTC_LB_HASH_FIELD_EGRESS_NICKNAME   = 0x02000000,    /**< [TM.TMM.AT] egress nickname */

    CTC_LB_HASH_FIELD_INNER             = 0x80000000,   /**< [TM.TMM.AT] If set, means the input fields are inner */
};
typedef enum ctc_lb_hash_field_e ctc_lb_hash_field_t;

enum ctc_lb_hash_flag_e
{
    CTC_LB_HASH_FLAG_IPV4_SYMMETRIC_EN  = 0x00000001,  /**< [TM.TMM.AT] enable ipv4 symmetric hash. Only valid for CTC_LB_HASH_PKT_TYPE_NONE */
    CTC_LB_HASH_FLAG_IPV6_SYMMETRIC_EN  = 0x00000002,  /**< [TM.TMM.AT] enable ipv6 symmetric hash. Only valid for CTC_LB_HASH_PKT_TYPE_NONE */
    CTC_LB_HASH_FLAG_IPV6_ADDR_COLLAPSE = 0x00000004,  /**< [TM.TMM.AT] use ipv6 address compress mode. Only valid for CTC_LB_HASH_PKT_TYPE_NONE */ 
    CTC_LB_HASH_FLAG_USE_MAPPED_VLAN    = 0x00000008,  /**< [TM.TMM.AT] select mapped vlan (QinQ/vlanClass/ProtocolVlan/...). Only valid for CTC_LB_HASH_PKT_TYPE_NONE */
};
typedef enum ctc_lb_hash_flag_e ctc_lb_hash_flag_t;

enum ctc_lb_hash_type_e
{
    CTC_LB_HASH_TYPE_CRC8_POLY1,        /**< [TM.TMM.AT] CRC8_POLY1  x8+x7+x2+x+1*/
    CTC_LB_HASH_TYPE_CRC8_POLY2,        /**< [TM.TMM.AT] CRC8_POLY2  x8+x7+x6+x+1, TMM:CTC_LB_HASH_TYPE_XOR8 8bit as low
                                                      and CTC_LB_HASH_TYPE_CRC16_POLY5 high 8 bit as high*/
    CTC_LB_HASH_TYPE_XOR8,              /**< [TM.TMM.AT] XOR8*/
    CTC_LB_HASH_TYPE_CRC10_POLY1,       /**< [TM] CRC10_POLY1  x10+x3+1*/
    CTC_LB_HASH_TYPE_CRC10_POLY2,       /**< [TM] CRC10_POLY2  x10+x7+1*/
    CTC_LB_HASH_TYPE_XOR16,             /**< [TM.TMM.AT] XOR16*/
    CTC_LB_HASH_TYPE_CRC16_POLY1,       /**< [TM] CRC16_POLY1  x16+x5+x3+x2+1*/
    CTC_LB_HASH_TYPE_CRC16_POLY2,       /**< [TM.TMM.AT] CRC16_POLY2  x16+x5+x4+x3+1*/
    CTC_LB_HASH_TYPE_CRC16_POLY3,       /**< [TM] CRC16_POLY3  x16+x10+x5+x3+1*/
    CTC_LB_HASH_TYPE_CRC16_POLY4,       /**< [TM] CRC16_POLY4  x16+x9+x4+x2+1*/
    CTC_LB_HASH_TYPE_CRC16_POLY5,       /**< [TMM.AT] CRC16_BISYNC  x16+x15+x2+1*/
    CTC_LB_HASH_TYPE_CRC16_POLY6,       /**< [TMM.AT] CRC16_CCITT  x16+x12+x5+1*/
    CTC_LB_HASH_TYPE_CRC32_POLY1,       /**< [TMM.AT] CRC32_POLY1  x32+x8+x5+x2+1, use low 16bit*/
    CTC_LB_HASH_TYPE_CRC32_POLY2,       /**< [TMM.AT] CRC32_POLY1  x32+x8+x5+x2+1, use high 16bit*/
    CTC_LB_HASH_TYPE_POLY_MAX

};
typedef enum ctc_lb_hash_type_e ctc_lb_hash_type_t;

enum ctc_lb_hash_pkt_type_e
{
    CTC_LB_HASH_PKT_TYPE_NONE,     /**< [TM.TMM.AT] Config for all packet type */
    CTC_LB_HASH_PKT_TYPE_L2,       /**< [TM.TMM.AT] L2 packet */
    CTC_LB_HASH_PKT_TYPE_IPV4,     /**< [TM.TMM.AT] IPV4 packet.
                                                    sub_type 0: All sub_type, 1: IPv4 in IPv4, 2: IPv6 in IPv4 */
    CTC_LB_HASH_PKT_TYPE_IPV6,     /**< [TM.TMM.AT] IPV6 packet.
                                                    sub_type 0: All sub_type, 1: IPv6 inner is IPv4, 2: IPv6 inner is IPv6 */
    CTC_LB_HASH_PKT_TYPE_MPLS,     /**< [TM.TMM.AT] MPLS packet.
                                                    sub_type 0: All sub_type, 1: L3VPN inner is IPv4, 2: L3VPN inner is IPv6,
                                                             3: VPLS, 4: VPWS(not support inner) */
    CTC_LB_HASH_PKT_TYPE_VXLAN,    /**< [TM.TMM.AT] VXLAN packet.
                                                    sub_type 0: All sub_type, 1: IPv4 VxLAN, 2: IPv6 VxLAN */
    CTC_LB_HASH_PKT_TYPE_GRE,      /**< [TM.TMM.AT] GRE packet.
                                                    sub_type 0: All sub_type, 1: IPv4 GRE not NvGRE, 2: IPv6 GRE not NvGRE,
                                                             3: IPv4 NvGRE, 4: IPv6 NvGRE */
    CTC_LB_HASH_PKT_TYPE_TRILL,    /**< [TM.TMM.AT] TRILL packet */
    CTC_LB_HASH_PKT_TYPE_FCOE,     /**< [TM.TMM.AT] FCOE packet */
    CTC_LB_HASH_PKT_TYPE_UDF,      /**< [TM.TMM.AT] UDF data as hash key, refer to ctc_lb_hash_fields_t, use 'data' to config UDF mask(128bit), 'fields0' to config field mask (14bit)
                                                    field: |  hit  |  UDF  |   UDF   |  UDF   |  UDF  |  UDF  |  UDF  |  UDF  |  UDF  | UDF  | dst  | dst  | src  | dst  |
                                                           | index | valid | 127-112 | 111-96 | 95-80 | 79-64 | 63-48 | 47-32 | 31-16 | 15-0 | Chip | Port | Chip | Port | */
    CTC_LB_HASH_PKT_TYPE_MAX
};
typedef enum ctc_lb_hash_pkt_type_e ctc_lb_hash_pkt_type_t;

struct ctc_lb_hash_fields_s
{
     uint8  sel_grp_id;       /**< [TM.TMM.AT] selector group id <0-7>, TM:<0-3>*/
     uint8  udf_profile_id;   /**< [TM.TMM.AT] <1-7>, udf profile id from scl model, valid for CTC_LB_HASH_PKT_TYPE_UDF */
     uint32 packet_type;      /**< [TM.TMM.AT] packet type enum, refer to ctc_lb_hash_pkt_type_t.*/
     uint8  sub_type;         /**< [AT] sub packet type, refer to ctc_lb_hash_pkt_type_t */

     uint32 fields0;          /**< [TM.TMM.AT] bitmap value, refer to ctc_lb_hash_field_t */
     uint32 fields1;          /**< [AT] bitmap value, refer to ctc_lb_hash_field_t. if set, means use fields0 + fields1 do hash
                                        e.g. L2(fields0) + L3(fields1) / outer(fields0) + inner(fields1) */
     void*  data;             /**< [TM.TMM.AT] extend data */
     uint32 flag;             /**< [TM.TMM.AT] hash control flag, refer to ctc_lb_hash_flag_t */
};
typedef struct ctc_lb_hash_fields_s ctc_lb_hash_fields_t;

struct ctc_lb_hash_poly_s
{
     uint8   sel_grp_id;      /**< [TM.TMM.AT] selector group id <0-7>, TM:<0-3>*/
     uint8   mode;            /**< [TM.TMM.AT] udf mode
                                        1: select 32bit UDF data replace seed;
                                        2: select 32bit UDF data add to hash key, refer to ctc_lb_hash_field_t; 
                                        3: [AT] select 16bit UDF data as hash value without calculate. The variable 'seed' means 16bit udf mask*/
     uint8   udf_offset;      /**< [TM.TMM.AT] udf offset*/
     uint32  seed;            /**< [TM.TMM.AT] hash seed*/
     uint8   poly_type;       /**< [TM.TMM.AT] hash poly, refer to ctc_lb_hash_type_t*/
};
typedef struct ctc_lb_hash_poly_s ctc_lb_hash_poly_t;

enum ctc_lb_hash_module_type_e
{
    CTC_LB_HASH_MODULE_LINKAGG,     /**< [TM.TMM.AT] linkagg module*/
    CTC_LB_HASH_MODULE_ECMP,        /**< [TM.TMM.AT] ecmp module*/
    CTC_LB_HASH_MODULE_STACKING,    /**< [TM.TMM.AT] stacking module*/
    CTC_LB_HASH_MODULE_HEAD_ECMP,   /**< [TM.TMM] for ecmp packet head which use as nexthop edit*/
    CTC_LB_HASH_MODULE_HEAD_LAG,    /**< [TM.TMM] for linkagg or stacking packet header hash*/
};
typedef enum ctc_lb_hash_module_type_e ctc_lb_hash_module_type_t;

enum ctc_lb_hash_mode_e
{
    CTC_LB_HASH_MODE_NONE,          /**< [TM.TMM.AT] all mode, only for CTC_LB_HASH_MODULE_ECMP*/
    CTC_LB_HASH_MODE_STATIC,        /**< [TM.TMM.AT] static mode*/
    CTC_LB_HASH_MODE_DLB_FLOW_SET,  /**< [TM.TMM.AT] set dlb flow */
    CTC_LB_HASH_MODE_DLB_MEMBER,    /**< [TM.TMM.AT] only for CTC_LB_HASH_MODULE_ECMP */
    CTC_LB_HASH_MODE_LSH,           /**< [TMM.AT] link self healing mode, for CTC_LB_HASH_MODULE_LINKAGG or CTC_LB_HASH_MODULE_STACKING*/
};
typedef enum ctc_lb_hash_mode_e ctc_lb_hash_mode_t;


enum ctc_lb_hash_fwd_type_e
{
    CTC_LB_HASH_FWD_NONE,       /**< [TM.TMM.AT] all packet type, only for CTC_LB_HASH_MODULE_ECMP*/
    CTC_LB_HASH_FWD_UC,         /**< [TM.TMM.AT] unicast message*/
    CTC_LB_HASH_FWD_NON_UC,     /**< [TM.TMM.AT] non unicast message*/
    CTC_LB_HASH_FWD_VXLAN,      /**< [TM.TMM.AT] only for CTC_LB_HASH_MODULE_ECMP */
    CTC_LB_HASH_FWD_NVGRE,      /**< [TM.TMM.AT] only for CTC_LB_HASH_MODULE_ECMP */
    CTC_LB_HASH_FWD_MPLS,       /**< [TM.TMM.AT] only for CTC_LB_HASH_MODULE_ECMP */
    CTC_LB_HASH_FWD_IP,         /**< [TM.TMM.AT] only for CTC_LB_HASH_MODULE_ECMP */
};
typedef enum ctc_lb_hash_fwd_type_e ctc_lb_hash_fwd_type_t;

struct ctc_lb_hash_offset_s
{
    uint8 profile_id;           /**< [TM.TMM.AT] set port acl or scl profile_id, 0xFF is global profile*/
    uint8 hash_module;          /**< [TM.TMM.AT] refer to ctc_lb_hash_module_type_t*/
    uint8 hash_mode;            /**< [TM.TMM.AT] refer to ctc_lb_hash_mode_t*/
    uint8 fwd_type;             /**< [TM.TMM.AT] refer to ctc_lb_hash_fwd_type_t*/
    
    uint16 offset;              /**< [TM.TMM.AT] <0-127>, if set 16, means select 16-31 bits, use CTC_LB_HASH_OFFSET_DISABLE to disable */
    uint8 use_entropy_hash;     /**< [TM.TMM.AT] only for CTC_LB_HASH_MODULE_ECMP */
    uint8 use_packet_head_hash; /**< [TM.TMM.AT] IF enable, use packet head hash, high priority than offset */
    uint8 hecmp_grp_en;         /**< [TMM.AT] only for CTC_LB_HASH_MODULE_ECMP */
};
typedef struct ctc_lb_hash_offset_s ctc_lb_hash_offset_t;

/*offset usage refer to ctc_lb_hash_offset_t note*/
struct ctc_lb_hash_global_property_s
{
    uint32 linkagg_lsh_hash_offset;   /**< [TMM.AT] link self healing global hash offset for port Linkagg */
    uint32 linkagg_spm_hash_offset;   /**< [TMM.AT] session preservation mechanism Flow LB global hash offset, select 16bit hash value but only high 4 bit useful*/
    uint32 stacking_lsh_hash_offset;  /**< [TMM.AT] link self healing global hash offset for stacking trunk*/
    uint8  stacking_port_hash_en;     /**< [TM.TMM.AT] value 0-2. 
                                            0: use profile hash offset or group hash offset(profile priority is higher)
                                            1: use hash value from port
                                            2: use global profile hash offset or header hash(header hash priority is higher)*/
};
typedef struct ctc_lb_hash_global_property_s ctc_lb_hash_global_property_t;

struct ctc_lb_hash_selector_ext_s
{
    uint32 sel_grp_id;       /**< [AT] extern selector group id, AT:<8-11> */
    uint32 sel_grp_bitmap;   /**< [AT] merge two physical selectors(0~7) that generated selector has two selector's information */
};
typedef struct ctc_lb_hash_selector_ext_s ctc_lb_hash_selector_ext_t;

struct ctc_lb_hash_selector_remap_s
{
    uint32 packet_type;                       /**< [AT] packet type enum, refer to ctc_lb_hash_pkt_type_t */  
    uint8  sub_type;                          /**< [AT] sub packet type, refer to ctc_lb_hash_pkt_type_t */  
    uint32 sel_grp_id[CTC_LB_HASH_GRP_NUM];   /**< [AT] map 8 physical selectors(0~7) and 4 extern selectors(8~11) to 8 final selectors, index is final selector id */
};
typedef struct ctc_lb_hash_selector_remap_s ctc_lb_hash_selector_remap_t;


#ifdef __cplusplus
}

#endif

#endif

